/* Copyright 2009
 *
 * This program and the accompanying materials
 * are made available under the terms of the
 * Eclipse Public License v1.0 which accompanies
 * this distribution, and is available at
 *
 * 		http://www.eclipse.org/legal/epl-v10.html
 *
 * Unless required by applicable law or agreed to in
 * writing, software distributed under the License is
 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
 * OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing
 * permissions and limitations under the License.
 *
 * Contributors:
 * 	   IBM Corporation - initial API and implementation for JDT/DLTK
 *     Sean W. Quinn - initial adoption for use with PHP from various sources.
 */
package org.eclipse.php.internal.ui.preferences.formatter.profile;

import java.util.Collection;
import java.util.Iterator;
import java.util.Map;

import org.eclipse.dltk.ui.formatter.IProfile;

/**
 * <p>
 * Represents a code formatter profile, with a unique <tt>ID</tt>, a name and a
 * map containing the code formatter settings.
 * </p>
 *
 * @author Sean W. Quinn (swquinn@gmail.com)
 */
public abstract class PHPProfile implements IProfile {
  /**
   * A prefix which is prepended to every ID of a user-defined profile, in order
   * to differentiate it from a built-in profile.
   */
  public final static String ID_PREFIX = "_"; //$NON-NLS-1$

  /**
   * The ID of this formatter profile.
   */
  private final String id;

  /**
   * The current kind of profile.
   */
  private final String kind;

  /**
   * The name of this formatter profile.
   */
  private String name;

  /**
   * The formatter settings for this profile.
   */
  private Map<String, String> formatterSettings;

  /**
   * The current version of this profile.
   */
  private int version;

  /**
   * @return the profile ID.
   */
  public String getID() {
    return id;
  }

  /**
	 *
	 */
  public String getFormatterId() {
    return id;
  }

  /**
   * @return the name of the profile.
   */
  public String getName() {
    return name;
  }

  /**
   *
   * @param name the name to set.
   */
  protected void setName(final String name) {
    this.name = name;
  }

  /**
   * @return the current version of this <code>Profile</code>.
   */
  public int getVersion() {
    return version;
  }

  /**
   * @return the kind of <code>Profile</code>.
   */
  public String getKind() {
    return kind;
  }

  /**
   * @return the code formatter settings associated with this profile.
   */
  public Map<String, String> getSettings() {
    return formatterSettings;
  }

  /**
   * @param settings
   */
  public abstract void setSettings(Map<String, String> formatterSettings);

  /**
   * @param name
   * @param formatterSettings
   * @param order
   * @param currentVersion
   * @param profileKind
   */
  public PHPProfile(final String name,
      final Map<String, String> formatterSettings, final int currentVersion,
      String profileKind) {
    this(ID_PREFIX + name, name, formatterSettings, currentVersion, profileKind);
  }

  /**
   * @param ID the ID of this <code>Profile</code>.
   * @param name the name of this <code>Profile</code>.
   * @param formatterSettings the formatter settings for this
   *          <code>Profile</code>.
   * @param order the cardinality of this <code>Profile</code>
   * @param currentVersion the current version of this <code>Profile</code>.
   * @param profileKind the type of this <code>Profile</code>.
   */
  public PHPProfile(final String ID, final String name,
      final Map<String, String> formatterSettings, final int version,
      String profileKind) {
    this.id = ID;
    this.name = name;
    this.formatterSettings = formatterSettings;
    this.version = version;
    this.kind = profileKind;
  }

  /**
   * @param settings
   */
  protected void setSettingsInternal(Map<String, String> formatterSettings) {
    this.formatterSettings = formatterSettings;
  }

  /**
   *
   * @param version
   */
  protected void setVersionInternal(final int version) {
    this.version = version;
  }

  /**
   *
   */
  public boolean equalsTo(Map<String, String> otherMap) {
    final Map<String, String> settings = getSettings();
    otherMap.entrySet();
    for (final Map.Entry<String, String> entry : otherMap.entrySet()) {
      final String existing = settings.get(entry.getKey());
      if (!entry.getValue().equals(existing)) {
        return false;
      }
    }
    return true;
  }

  public boolean hasEqualSettings(final Map<String, String> otherMap,
      final Collection<String> allKeys) {
    final Map<String, String> settings = getSettings();
    for (Iterator<String> iter = allKeys.iterator(); iter.hasNext();) {
      final String key = (String) iter.next();
      final Object other = otherMap.get(key);
      Object curr = settings.get(key);
      if (other == null) {
        if (curr != null) {
          return false;
        }
      }
      else if (!other.equals(curr)) {
        return false;
      }
    }
    return true;
  }

  /**
   * @return <tt>false</tt>, a default {@link PHPProfile} instance is neither
   *         shared nor is it built-in.
   */
  public boolean isBuiltInProfile() {
    return false;
  }

  /**
   * @return <tt>false</tt>, a default {@link PHPProfile} instance is neither
   *         shared nor is it built-in.
   */
  public boolean isSharedProfile() {
    return false;
  }

  /**
   * @return
   */
  public abstract boolean isProfileToSave();

  /**
   * <p>
   * Renames a profile to the <tt>name</tt> passed.
   * </p>
   *
   * @param name the new name to attribute to this profile.
   * @param manager the profile manager.
   * @return the renamed <code>Profile</code>.
   */
  public abstract PHPProfile rename(String name, PHPProfileManager manager);
}
